{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2 数据结构"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.1 GeoSeries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1.1 GeoSeries中的基础几何对象"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **Points**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    POINT (0.00000 0.00000)\n",
       "b    POINT (0.00000 1.00000)\n",
       "c    POINT (1.00000 1.00000)\n",
       "d    POINT (1.00000 0.00000)\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from shapely import geometry\n",
    "import geopandas as gpd\n",
    "\n",
    "# 创建存放Point对象的GeoSeries\n",
    "# 这里shapely.geometry.Point(x, y)用于创建单个点对象\n",
    "gpd.GeoSeries([geometry.Point(0, 0),\n",
    "               geometry.Point(0, 1),\n",
    "               geometry.Point(1, 1),\n",
    "               geometry.Point(1, 0)],\n",
    "              index=['a', 'b', 'c', 'd'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **MultiPoint**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    MULTIPOINT (0.00000 1.00000, 1.00000 0.00000)\n",
       "b    MULTIPOINT (0.00000 0.00000, 1.00000 1.00000)\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放MultiPoint对象的GeoSeries\n",
    "# 这里shapely.geometry.MultiPoint([(x1, y1), (x2, y2), ...])用于创建多点集合\n",
    "gpd.GeoSeries([geometry.MultiPoint([(0, 1), (1, 0)]),\n",
    "               geometry.MultiPoint([(0, 0), (1, 1)])],\n",
    "              index=['a', 'b'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.04 -0.04 1.08 1.08\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><g><circle cx=\"0.0\" cy=\"1.0\" r=\"0.0324\" stroke=\"#555555\" stroke-width=\"0.0108\" fill=\"#66cc99\" opacity=\"0.6\" /><circle cx=\"1.0\" cy=\"0.0\" r=\"0.0324\" stroke=\"#555555\" stroke-width=\"0.0108\" fill=\"#66cc99\" opacity=\"0.6\" /></g></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.multipoint.MultiPoint at 0x2b2ce22b108>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.MultiPoint([(0, 1), (1, 0)]),\n",
    "               geometry.MultiPoint([(0, 0), (1, 1)])],\n",
    "              index=['a', 'b'])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **LineString**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    LINESTRING (0.00000 0.00000, 1.00000 1.00000, ...\n",
       "b    LINESTRING (0.00000 0.00000, 0.00000 1.00000, ...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放LineString对象的GeoSeries\n",
    "# 这里shapely.geometry.LineString([(x1, y1), (x2, y2), ...])用于创建多点按顺序连接而成的线段\n",
    "gpd.GeoSeries([geometry.LineString([(0, 0), (1, 1), (1, 0)]),\n",
    "               geometry.LineString([(0, 0), (0, 1), (-1, 0)])],\n",
    "              index=['a', 'b'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.04 -0.04 1.08 1.08\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><polyline fill=\"none\" stroke=\"#66cc99\" stroke-width=\"0.0216\" points=\"0.0,0.0 1.0,1.0 1.0,0.0\" opacity=\"0.8\" /></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.linestring.LineString at 0x2b2ce2355c8>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.LineString([(0, 0), (1, 1), (1, 0)]),\n",
    "               geometry.LineString([(0, 0), (0, 1), (-1, 0)])],\n",
    "              index=['a', 'b'])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **MultiLineString**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    MULTILINESTRING ((0.00000 0.00000, 1.00000 1.0...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放MultiLineString对象的GeoSeries\n",
    "# 这里shapely.geometry.MultiLineString([LineString1, LineString2])\n",
    "# 用于创建多条线段的集合\n",
    "gpd.GeoSeries([geometry.MultiLineString([[(0, 0), (1, 1), (1, 0)],\n",
    "                                        [(-0.5, 0), (0, 1), (-1, 0)]])],\n",
    "              index=['a'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-1.08 -0.08 2.16 1.1600000000000001\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><g><polyline fill=\"none\" stroke=\"#66cc99\" stroke-width=\"0.0432\" points=\"0.0,0.0 1.0,1.0 1.0,0.0\" opacity=\"0.8\" /><polyline fill=\"none\" stroke=\"#66cc99\" stroke-width=\"0.0432\" points=\"-0.5,0.0 0.0,1.0 -1.0,0.0\" opacity=\"0.8\" /></g></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.multilinestring.MultiLineString at 0x2b2ce23f608>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.MultiLineString([[(0, 0), (1, 1), (1, 0)],\n",
    "                                        [(-0.5, 0), (0, 1), (-1, 0)]])],\n",
    "              index=['a'])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **Polygon(无孔)**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    POLYGON ((0.00000 0.00000, 0.00000 1.00000, 1....\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放无孔Polygon对象的GeoSeries\n",
    "# 这里shapely.geometry.Polygon([(x1, y1), (x2, y2),...])用于创建无孔面\n",
    "gpd.GeoSeries([geometry.Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])],\n",
    "              index=['a'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.04 -0.04 1.08 1.08\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.0216\" opacity=\"0.6\" d=\"M 0.0,0.0 L 0.0,1.0 L 1.0,1.0 L 1.0,0.0 L 0.0,0.0 z\" /></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.polygon.Polygon at 0x2b2ce244408>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.Polygon([(0, 0), (0, 1), (1, 1), (1, 0)])],\n",
    "              index=['a'])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **Polygon(有孔)**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    POLYGON ((0.00000 0.00000, 10.00000 0.00000, 1...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放有孔Polygon对象的GeoSeries\n",
    "# 这里shapely.geometry.Polygon(polygonExteriors, interiorCoords)用于创建有孔面\n",
    "# 其中polygonExteriors用于定义整个有孔Polygon的外围，是一个无孔的多边形\n",
    "# interiorCoords是用于定义内部每个孔洞（本质上是独立的多边形）的序列\n",
    "gpd.GeoSeries([geometry.Polygon([(0,0),(10,0),(10,10),(0,10)], \n",
    "                                [((1,3),(5,3),(5,1),(1,1)), \n",
    "                                 ((9,9),(9,8),(8,8),(8,9))])])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.4 -0.4 10.8 10.8\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,10.0)\"><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.21600000000000003\" opacity=\"0.6\" d=\"M 0.0,0.0 L 10.0,0.0 L 10.0,10.0 L 0.0,10.0 L 0.0,0.0 z M 1.0,3.0 L 5.0,3.0 L 5.0,1.0 L 1.0,1.0 L 1.0,3.0 z M 9.0,9.0 L 9.0,8.0 L 8.0,8.0 L 8.0,9.0 L 9.0,9.0 z\" /></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.polygon.Polygon at 0x2b2cf22bec8>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.Polygon([(0,0),(10,0),(10,10),(0,10)], \n",
    "                                [((1,3),(5,3),(5,1),(1,1)), \n",
    "                                 ((9,9),(9,8),(8,8),(8,9))])])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **MultiPolygon**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    MULTIPOLYGON (((0.00000 0.00000, 0.00000 1.000...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放MultiPolygon对象的GeoSeries\n",
    "# 这里shapely.geometry.MultiPolygon([Polygon1, Polygon2])用于创建多个面的集合\n",
    "gpd.GeoSeries([geometry.MultiPolygon([geometry.Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]),\n",
    "                                      geometry.Polygon([(2, 2), (2, 3), (3, 3), (3, 2), (2, 2)])])],\n",
    "              index=['a'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.12 -0.12 3.24 3.24\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,3.0)\"><g><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.06480000000000001\" opacity=\"0.6\" d=\"M 0.0,0.0 L 0.0,1.0 L 1.0,1.0 L 1.0,0.0 L 0.0,0.0 z\" /><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.06480000000000001\" opacity=\"0.6\" d=\"M 2.0,2.0 L 2.0,3.0 L 3.0,3.0 L 3.0,2.0 L 2.0,2.0 z\" /></g></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.multipolygon.MultiPolygon at 0x2b2ce244f48>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.MultiPolygon([geometry.Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]),\n",
    "                                      geometry.Polygon([(2, 2), (2, 3), (3, 3), (3, 2), (2, 2)])])],\n",
    "              index=['a'])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **LinearRing**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "a    LINEARRING (0.00000 0.00000, 0.00000 1.00000, ...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建存放LinearRing对象的GeoSeries\n",
    "# 这里shapely.geometry.LinearRing([(x1, y1), (x2, y2),...])用于创建LinearRing\n",
    "gpd.GeoSeries([geometry.LinearRing([(0, 0), (0, 1), (1, 1), (1, 0)])],\n",
    "              index=['a'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"-0.04 -0.04 1.08 1.08\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><polyline fill=\"none\" stroke=\"#66cc99\" stroke-width=\"0.0216\" points=\"0.0,0.0 0.0,1.0 1.0,1.0 1.0,0.0 0.0,0.0\" opacity=\"0.8\" /></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.polygon.LinearRing at 0x2b2ce24e588>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpd.GeoSeries([geometry.LinearRing([(0, 0), (0, 1), (1, 1), (1, 0)])],\n",
    "              index=['a'])[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1.2 GeoSeries常用属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "3ce1863fc0b141cf9e9a54f04be2cdbd",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d2468508>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建混合点线面的GeoSeries，这里第5个有孔多边形内部空洞创建时使用[::-1]颠倒顺序\n",
    "# 是因为GeoSeries.plot()方法绘制有孔多边形的一个bug，即外部边框与内部孔洞创建时坐标\n",
    "# 方向同为顺时针或顺时针时内部孔洞会自动被填充，如果你对这个bug感兴趣，可以前往\n",
    "# https://github.com/geopandas/geopandas/issues/951查看细节\n",
    "s = gpd.GeoSeries([geometry.Polygon([(0, 0), (0.5, 0.5), (1, 0), (0.5, -0.5)]),\n",
    "                   geometry.Polygon([(1, 1), (1.5, 1.5), (2, 1), (1.5, -1.5)]),\n",
    "                   geometry.Point(3, 3),\n",
    "                   geometry.LineString([(2, 2), (0, 3)]),\n",
    "                   geometry.Polygon([(4, 4), (8, 4), (8, 8), (4, 8)], \n",
    "                                [[(5, 5), (7, 5), (7, 7), (5, 7)][::-1]])])\n",
    "\n",
    "# 在jupyter中开启matplotlib交互式绘图模式\n",
    "%matplotlib widget\n",
    "s.plot() # 对s进行简单的可视化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **area**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     0.5\n",
       "1     1.5\n",
       "2     0.0\n",
       "3     0.0\n",
       "4    12.0\n",
       "dtype: float64"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算s中各几何对象的面积\n",
    "s.area"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **bounds**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0                                        []\n",
       "1                                        []\n",
       "2                                      None\n",
       "3                                      None\n",
       "4    [LINEARRING (5 7, 7 7, 7 5, 5 5, 5 7)]\n",
       "dtype: object"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算s中各几何对象内部孔洞边界列表\n",
    "s.interiors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **length**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>minx</th>\n",
       "      <th>miny</th>\n",
       "      <th>maxx</th>\n",
       "      <th>maxy</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.0</td>\n",
       "      <td>-0.5</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.0</td>\n",
       "      <td>-1.5</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>8.0</td>\n",
       "      <td>8.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   minx  miny  maxx  maxy\n",
       "0   0.0  -0.5   1.0   0.5\n",
       "1   1.0  -1.5   2.0   1.5\n",
       "2   3.0   3.0   3.0   3.0\n",
       "3   0.0   2.0   2.0   3.0\n",
       "4   4.0   4.0   8.0   8.0"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算s中各几何对象box左下角与右上角的坐标\n",
    "s.bounds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **geom_type**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     2.828427\n",
       "1     6.513233\n",
       "2     0.000000\n",
       "3     2.236068\n",
       "4    24.000000\n",
       "dtype: float64"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算s中各几何对象边长\n",
    "s.length"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **exterior**与**interiors**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0       Polygon\n",
       "1       Polygon\n",
       "2         Point\n",
       "3    LineString\n",
       "4       Polygon\n",
       "dtype: object"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算s中各几何对象类型\n",
    "s.geom_type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    LINEARRING (0.00000 0.00000, 0.50000 0.50000, ...\n",
       "1    LINEARRING (1.00000 1.00000, 1.50000 1.50000, ...\n",
       "2                                                 None\n",
       "3                                                 None\n",
       "4    LINEARRING (4.00000 4.00000, 8.00000 4.00000, ...\n",
       "dtype: geometry"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算s中各几何对象外边界\n",
    "s.exterior"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **is_valid**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "s_ = gpd.GeoSeries([geometry.Polygon([(4, 0), (6, 1), (4, 1), (6, 0)]),\n",
    "               geometry.MultiPolygon([geometry.Polygon([(4, 0), (5, 0.5), (6, 0)]), \n",
    "                                      geometry.Polygon([(5, 0.5), (6, 1), (4, 1)])])])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"3.92 -0.08 2.16 1.1600000000000001\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><path fill-rule=\"evenodd\" fill=\"#ff3333\" stroke=\"#555555\" stroke-width=\"0.0432\" opacity=\"0.6\" d=\"M 4.0,0.0 L 6.0,1.0 L 4.0,1.0 L 6.0,0.0 L 4.0,0.0 z\" /></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.polygon.Polygon at 0x2b2d2dcaf88>"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s_[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"100.0\" height=\"100.0\" viewBox=\"3.92 -0.08 2.16 1.1600000000000001\" preserveAspectRatio=\"xMinYMin meet\"><g transform=\"matrix(1,0,0,-1,0,1.0)\"><g><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.0432\" opacity=\"0.6\" d=\"M 4.0,0.0 L 5.0,0.5 L 6.0,0.0 L 4.0,0.0 z\" /><path fill-rule=\"evenodd\" fill=\"#66cc99\" stroke=\"#555555\" stroke-width=\"0.0432\" opacity=\"0.6\" d=\"M 5.0,0.5 L 6.0,1.0 L 4.0,1.0 L 5.0,0.5 z\" /></g></g></svg>"
      ],
      "text/plain": [
       "<shapely.geometry.multipolygon.MultiPolygon at 0x2b2d2deb148>"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s_[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "TopologyException: Input geom 0 is invalid: Self-intersection at or near point 5 0.5 at 5 0.5\n"
     ]
    },
    {
     "ename": "TopologicalError",
     "evalue": "The operation 'GEOSIntersection_r' could not be performed. Likely cause is invalidity of the geometry <shapely.geometry.polygon.Polygon object at 0x000002B2D2DCAF88>",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTopologicalError\u001b[0m                          Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-27-ff09abafb74c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0ms_\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mintersection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms_\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\shapely\\geometry\\base.py\u001b[0m in \u001b[0;36mintersection\u001b[1;34m(self, other)\u001b[0m\n\u001b[0;32m    618\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0mintersection\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mother\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    619\u001b[0m         \u001b[1;34m\"\"\"Returns the intersection of the geometries\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 620\u001b[1;33m         \u001b[1;32mreturn\u001b[0m \u001b[0mgeom_factory\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mimpl\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'intersection'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mother\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    621\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    622\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0msymmetric_difference\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mother\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\shapely\\topology.py\u001b[0m in \u001b[0;36m__call__\u001b[1;34m(self, this, other, *args)\u001b[0m\n\u001b[0;32m     68\u001b[0m             err = TopologicalError(\n\u001b[0;32m     69\u001b[0m                     \"This operation could not be performed. Reason: unknown\")\n\u001b[1;32m---> 70\u001b[1;33m             \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_check_topology\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mthis\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mother\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     71\u001b[0m         \u001b[1;32mreturn\u001b[0m \u001b[0mproduct\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     72\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\shapely\\topology.py\u001b[0m in \u001b[0;36m_check_topology\u001b[1;34m(self, err, *geoms)\u001b[0m\n\u001b[0;32m     36\u001b[0m                     \u001b[1;34m\"The operation '%s' could not be performed. \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     37\u001b[0m                     \"Likely cause is invalidity of the geometry %s\" % (\n\u001b[1;32m---> 38\u001b[1;33m                         self.fn.__name__, repr(geom)))\n\u001b[0m\u001b[0;32m     39\u001b[0m         \u001b[1;32mraise\u001b[0m \u001b[0merr\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     40\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTopologicalError\u001b[0m: The operation 'GEOSIntersection_r' could not be performed. Likely cause is invalidity of the geometry <shapely.geometry.polygon.Polygon object at 0x000002B2D2DCAF88>"
     ]
    }
   ],
   "source": [
    "s_[0].intersection(s_[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    False\n",
       "1     True\n",
       "dtype: bool"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s_.is_valid"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **boundary**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "868ac322accf4c4891518648261b3b2d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d2eada08>"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回各几何对象的低维简化表示\n",
    "s.boundary.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **centroid**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8cfa8c4a156942c4a7e89fbac7f955ce",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d32ef348>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回各几何对象的重心\n",
    "ax = s.plot() # 绘制s\n",
    "s.centroid.plot(ax=ax, color='red') # 叠加绘制重心结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **convex_hull**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "65b85796768f4b4f96a5bd1f87ee939f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d2f4ed48>"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 创建两团独立的MultiPoint\n",
    "s__ = gpd.GeoSeries([geometry.MultiPoint(np.random.normal(loc=0, scale=2, size=[10, 2]).tolist()),\n",
    "               geometry.MultiPoint(np.random.normal(loc=5, scale=2, size=[10, 2]).tolist())])\n",
    "\n",
    "ax = s__.plot(color='red') # 绘制s__\n",
    "s__.convex_hull.plot(ax=ax, alpha=0.4) # 叠加绘制各自对应凸包"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **envelope**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f4833cbb20a74d9db6108e77c015a8bb",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d2f50448>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 创建两团独立的MultiPoint\n",
    "s__ = gpd.GeoSeries([geometry.MultiPoint(np.random.normal(loc=0, scale=2, size=[10, 2]).tolist()),\n",
    "               geometry.MultiPoint(np.random.normal(loc=5, scale=2, size=[10, 2]).tolist())])\n",
    "\n",
    "ax = s__.plot(color='red') # 绘制s__\n",
    "s__.envelope.plot(ax=ax, alpha=0.4) # 叠加绘制各自对应envelope，调低填充透明度以显示更明显"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 GeoDataFrame"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.1 GeoDataFrame基础"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>均值</th>\n",
       "      <th>标准差</th>\n",
       "      <th>geometry</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0.5</td>\n",
       "      <td>MULTIPOINT (0.18193 0.30002, 0.75158 0.38686, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>0.5</td>\n",
       "      <td>MULTIPOINT (1.43067 1.40640, 1.65145 1.01231, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>4</td>\n",
       "      <td>0.5</td>\n",
       "      <td>MULTIPOINT (4.20904 3.75744, 4.05318 4.61695, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>6</td>\n",
       "      <td>0.5</td>\n",
       "      <td>MULTIPOINT (6.01883 6.35274, 6.17306 5.76938, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8</td>\n",
       "      <td>0.5</td>\n",
       "      <td>MULTIPOINT (7.21866 7.38495, 8.29127 8.40514, ...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   均值  标准差                                           geometry\n",
       "0   0  0.5  MULTIPOINT (0.18193 0.30002, 0.75158 0.38686, ...\n",
       "1   2  0.5  MULTIPOINT (1.43067 1.40640, 1.65145 1.01231, ...\n",
       "2   4  0.5  MULTIPOINT (4.20904 3.75744, 4.05318 4.61695, ...\n",
       "3   6  0.5  MULTIPOINT (6.01883 6.35274, 6.17306 5.76938, ...\n",
       "4   8  0.5  MULTIPOINT (7.21866 7.38495, 8.29127 8.40514, ..."
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "contents = [(loc, 0.5) for loc in range(0, 10, 2)]\n",
    "geo_df = gpd.GeoDataFrame(data=contents, \n",
    "                          geometry=[geometry.MultiPoint(np.random.normal(loc=loc, scale=scale, size=[10, 2]).tolist()) \n",
    "                                    for loc, scale in contents],\n",
    "                          columns=['均值', '标准差'])\n",
    "geo_df"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **添加矢量列但未定义**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "No geometry data set yet (expected in column 'geometry'.",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-34-c428d8c1fe26>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      3\u001b[0m                                     for loc, scale in contents]\n\u001b[0;32m      4\u001b[0m \u001b[1;31m# 尝试查看矢量类型\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mgeo_df\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgeom_type\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\pandas\\core\\generic.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m   5272\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_info_axis\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_can_hold_identifiers_and_holds_name\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   5273\u001b[0m                 \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 5274\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0mobject\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__getattribute__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   5275\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   5276\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0m__setattr__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\geopandas\\base.py\u001b[0m in \u001b[0;36mgeom_type\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m    140\u001b[0m         \"\"\"Returns a ``Series`` of strings specifying the `Geometry Type` of each\n\u001b[0;32m    141\u001b[0m         object.\"\"\"\n\u001b[1;32m--> 142\u001b[1;33m         \u001b[1;32mreturn\u001b[0m \u001b[0m_delegate_property\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"geom_type\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    143\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    144\u001b[0m     \u001b[1;33m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\geopandas\\base.py\u001b[0m in \u001b[0;36m_delegate_property\u001b[1;34m(op, this)\u001b[0m\n\u001b[0;32m     77\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_delegate_property\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mop\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mthis\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     78\u001b[0m     \u001b[1;31m# type: (str, GeoSeries) -> GeoSeries/Series\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 79\u001b[1;33m     \u001b[0ma_this\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mGeometryArray\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mthis\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgeometry\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     80\u001b[0m     \u001b[0mdata\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma_this\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mop\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     81\u001b[0m     \u001b[1;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mGeometryArray\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\pandas\\core\\generic.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m   5272\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_info_axis\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_can_hold_identifiers_and_holds_name\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   5273\u001b[0m                 \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 5274\u001b[1;33m             \u001b[1;32mreturn\u001b[0m \u001b[0mobject\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__getattribute__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m   5275\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   5276\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0m__setattr__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mname\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m->\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mC:\\Anaconda\\lib\\site-packages\\geopandas\\geodataframe.py\u001b[0m in \u001b[0;36m_get_geometry\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m    101\u001b[0m             raise AttributeError(\n\u001b[0;32m    102\u001b[0m                 \u001b[1;34m\"No geometry data set yet (expected in\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 103\u001b[1;33m                 \u001b[1;34m\" column '%s'.\"\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_geometry_column_name\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    104\u001b[0m             )\n\u001b[0;32m    105\u001b[0m         \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_geometry_column_name\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAttributeError\u001b[0m: No geometry data set yet (expected in column 'geometry'."
     ]
    }
   ],
   "source": [
    "geo_df = gpd.GeoDataFrame(contents, columns=['均值', '标准差'])\n",
    "geo_df['raw_points'] = [geometry.MultiPoint(np.random.normal(loc=loc, scale=scale, size=[10, 2]).tolist()) \n",
    "                                    for loc, scale in contents]\n",
    "# 尝试查看矢量类型\n",
    "geo_df.geom_type"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **重新为`GeoDataFrame`指定矢量列**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    MultiPoint\n",
       "1    MultiPoint\n",
       "2    MultiPoint\n",
       "3    MultiPoint\n",
       "4    MultiPoint\n",
       "dtype: object"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_df.set_geometry('raw_points').geom_type"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **多个矢量列切换**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "89649890e1aa4784940a25105f3a6c16",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d310ea48>"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "geo_df = gpd.GeoDataFrame(contents, columns=['均值', '标准差'])\n",
    "geo_df['raw_points'] = [geometry.MultiPoint(np.random.normal(loc=loc, scale=scale, size=[10, 2]).tolist()) \n",
    "                                    for loc, scale in contents]\n",
    "geo_df.set_geometry('raw_points', inplace=True) # inplace=True表示对原数据进行更新\n",
    "\n",
    "# 绘制第一图层\n",
    "ax = geo_df.plot(color='red')\n",
    "geo_df['convex_hull'] = geo_df.convex_hull\n",
    "# 切换矢量主列\n",
    "geo_df.set_geometry('convex_hull', inplace=True)\n",
    "\n",
    "# 绘制第二图层\n",
    "geo_df.plot(ax=ax, color='blue', alpha=0.4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2.2 GeoDataFrame数据索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f2d7eaacb5e8450db7ac69e5221bb330",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x2b2d31e71c8>"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))\n",
    "world.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pop_est</th>\n",
       "      <th>continent</th>\n",
       "      <th>name</th>\n",
       "      <th>iso_a3</th>\n",
       "      <th>gdp_md_est</th>\n",
       "      <th>geometry</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>920938</td>\n",
       "      <td>Oceania</td>\n",
       "      <td>Fiji</td>\n",
       "      <td>FJI</td>\n",
       "      <td>8374.0</td>\n",
       "      <td>MULTIPOLYGON (((180.00000 -16.06713, 180.00000...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>53950935</td>\n",
       "      <td>Africa</td>\n",
       "      <td>Tanzania</td>\n",
       "      <td>TZA</td>\n",
       "      <td>150600.0</td>\n",
       "      <td>POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>603253</td>\n",
       "      <td>Africa</td>\n",
       "      <td>W. Sahara</td>\n",
       "      <td>ESH</td>\n",
       "      <td>906.5</td>\n",
       "      <td>POLYGON ((-8.66559 27.65643, -8.66512 27.58948...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>35623680</td>\n",
       "      <td>North America</td>\n",
       "      <td>Canada</td>\n",
       "      <td>CAN</td>\n",
       "      <td>1674000.0</td>\n",
       "      <td>MULTIPOLYGON (((-122.84000 49.00000, -122.9742...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>326625791</td>\n",
       "      <td>North America</td>\n",
       "      <td>United States of America</td>\n",
       "      <td>USA</td>\n",
       "      <td>18560000.0</td>\n",
       "      <td>MULTIPOLYGON (((-122.84000 49.00000, -120.0000...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     pop_est      continent                      name iso_a3  gdp_md_est  \\\n",
       "0     920938        Oceania                      Fiji    FJI      8374.0   \n",
       "1   53950935         Africa                  Tanzania    TZA    150600.0   \n",
       "2     603253         Africa                 W. Sahara    ESH       906.5   \n",
       "3   35623680  North America                    Canada    CAN   1674000.0   \n",
       "4  326625791  North America  United States of America    USA  18560000.0   \n",
       "\n",
       "                                            geometry  \n",
       "0  MULTIPOLYGON (((180.00000 -16.06713, 180.00000...  \n",
       "1  POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...  \n",
       "2  POLYGON ((-8.66559 27.65643, -8.66512 27.58948...  \n",
       "3  MULTIPOLYGON (((-122.84000 49.00000, -122.9742...  \n",
       "4  MULTIPOLYGON (((-122.84000 49.00000, -120.0000...  "
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "world.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pop_est</th>\n",
       "      <th>name</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>98</th>\n",
       "      <td>1281935911</td>\n",
       "      <td>India</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>139</th>\n",
       "      <td>1379302771</td>\n",
       "      <td>China</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        pop_est   name\n",
       "98   1281935911  India\n",
       "139  1379302771  China"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择人口在10亿以上的pop_est、name列\n",
    "world.loc[world['pop_est'] >= 1000000000, ['pop_est', 'name']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pop_est</th>\n",
       "      <th>continent</th>\n",
       "      <th>name</th>\n",
       "      <th>iso_a3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>920938</td>\n",
       "      <td>Oceania</td>\n",
       "      <td>Fiji</td>\n",
       "      <td>FJI</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>53950935</td>\n",
       "      <td>Africa</td>\n",
       "      <td>Tanzania</td>\n",
       "      <td>TZA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>603253</td>\n",
       "      <td>Africa</td>\n",
       "      <td>W. Sahara</td>\n",
       "      <td>ESH</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>35623680</td>\n",
       "      <td>North America</td>\n",
       "      <td>Canada</td>\n",
       "      <td>CAN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>326625791</td>\n",
       "      <td>North America</td>\n",
       "      <td>United States of America</td>\n",
       "      <td>USA</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>18556698</td>\n",
       "      <td>Asia</td>\n",
       "      <td>Kazakhstan</td>\n",
       "      <td>KAZ</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>29748859</td>\n",
       "      <td>Asia</td>\n",
       "      <td>Uzbekistan</td>\n",
       "      <td>UZB</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>6909701</td>\n",
       "      <td>Oceania</td>\n",
       "      <td>Papua New Guinea</td>\n",
       "      <td>PNG</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>260580739</td>\n",
       "      <td>Asia</td>\n",
       "      <td>Indonesia</td>\n",
       "      <td>IDN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>44293293</td>\n",
       "      <td>South America</td>\n",
       "      <td>Argentina</td>\n",
       "      <td>ARG</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     pop_est      continent                      name iso_a3\n",
       "0     920938        Oceania                      Fiji    FJI\n",
       "1   53950935         Africa                  Tanzania    TZA\n",
       "2     603253         Africa                 W. Sahara    ESH\n",
       "3   35623680  North America                    Canada    CAN\n",
       "4  326625791  North America  United States of America    USA\n",
       "5   18556698           Asia                Kazakhstan    KAZ\n",
       "6   29748859           Asia                Uzbekistan    UZB\n",
       "7    6909701        Oceania          Papua New Guinea    PNG\n",
       "8  260580739           Asia                 Indonesia    IDN\n",
       "9   44293293  South America                 Argentina    ARG"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择前10行，前4列的数据\n",
    "world.iloc[:10, :4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "23a791cf432049a491bc0b31cef8e399",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 选择与东经80度-110度，北纬0度-30度范围相交的几何对象\n",
    "part_world = world.cx[80:110, 0:30]\n",
    "\n",
    "# 绘制第一图层：世界地图\n",
    "ax = world.plot(alpha=0.05)\n",
    "# 绘制第二图层：.cx所选择的地区\n",
    "ax = part_world.plot(ax=ax, alpha=0.6)\n",
    "# 绘制第三图层：.cx条件示意图\n",
    "ax = gpd.GeoSeries([geometry.box(minx=80, miny=0, maxx=110, maxy=30).boundary])\\\n",
    "    .plot(ax=ax, color='red')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
